/**
 * Created by Harrie on 2015/10/12 0012.
 */
var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),
    tools = require('./tools');
//options
var allowPostImg = true;

//静态文件映射
app.use('/', express.static(__dirname + '/www'));

//监听端口
server.listen(80);
console.log("server started on port:80");

var Room = function (roomName) {
    this.id = tools.generateId();
    this.name = roomName;
    this.users = [];
};

var User = function (userName) {
    this.id = tools.generateId();
    this.name = userName;
};

var EmitType = {
    Normal: 'normal',
    Broadcast: 'broadcast',
    Room: 'room',
    Outer: 'outer'
};

var MsgTemplate = {
    LoginEmit: '欢迎使用Minechat！',
    LoginBroadcast: '{0}进入聊天室。',
    LogOutBroadcast: '{0}离开聊天室。',
    RoomNotFound: '房间不存在。',
    DuplicateName: '昵称"{0}"已被使用。',
    QuoteUser: '<b class="highlight">{0}</b>',
    FaceEmoji: '<img class="face emoji" src="./content/face/emoji/{0}.png"/>',
    FaceTuzki: '<img class="face tuzji" src="./content/face/tuzki/{0}.gif"/>',
    ImgMsg: '<a href="{0}" target="_blank"><img class="img" src="{0}"/></a>'
};

function emit(socket, type, label, data) {
    switch (type) {
        case EmitType.Normal:
            socket.emit(label, new Date().getTime(), data);
            break;
        case EmitType.Broadcast:
            socket.broadcast.to(socket.roomId).emit(label, new Date().getTime(), data);
            break;
        case  EmitType.Room:
            io.in(socket.roomId).emit(label, new Date().getTime(), data);
            break;
        case EmitType.Outer:
            io.emit(label, new Date().getTime(), data);
            break;
    }
}

function joinRoom(socket, roomId, userName) {
    //房间号是否存在
    if (!rooms[roomId]) {
        emit(socket, EmitType.Normal, 'loginFail', {msg: MsgTemplate.RoomNotFound});
        return false;
    }

    //用户名是否重复
    var users = rooms[roomId].users;
    if (tools.indexOf(users, function (i, v) {
            return v.name == userName;
        }) >= 0) {
        emit(socket, EmitType.Normal, 'loginFail', {msg: tools.format(MsgTemplate.DuplicateName, userName)});
        return false;
    }

    //设置昵称
    if (!socket.user)
        socket.user = new User(userName);
    else
        socket.user.name = userName;

    //进入房间
    users.push(socket.user);
    socket.join(roomId);
    socket.roomId = roomId;
    var roomName = rooms[roomId].name;
    emit(socket, EmitType.Normal, 'loginSuccess', {
        msg: MsgTemplate.LoginEmit,
        roomName: roomName,
        users: users,
        allowPostImg: allowPostImg
    });
    emit(socket, EmitType.Broadcast, 'usersUpdate', {
        msg: tools.format(MsgTemplate.LoginBroadcast, userName),
        users: users
    });
    return true;
}

function leaveRoom(socket) {
    var user = socket.user,
        userName = user.name,
        roomId = socket.roomId,
        users = rooms[roomId].users;

    //从房间列表中移除
    tools.removeFrom(users, function (i, v) {
        return v.id == user.id;
    });
    emit(socket, EmitType.Broadcast, 'usersUpdate', {
        msg: tools.format(MsgTemplate.LogOutBroadcast, userName),
        users: users
    });

    //清理空房间
    if (users.length == 0 && roomId != 0) {
        delete rooms[roomId];
        roomsChanged();
    }

    //离开房间
    socket.leave(roomId);
    socket.roomId = null;
}

function createRoom(roomName) {
    var room = new Room(roomName);
    rooms[room.id] = room;
    roomsChanged();
    return room.id;
}

function roomsChanged() {
    var roomsMini = [];
    for (var roomId in rooms) {
        if (rooms[roomId] && rooms[roomId].users) {
            roomsMini.push({
                id: roomId,
                name: rooms[roomId].name,
                count: rooms[roomId].users.length
            });
        }
    }
    emit(null, EmitType.Outer, 'roomsUpdate', {rooms: roomsMini});
}

var rooms = [];
var room = new Room('默认房间');
room.id = 0;
rooms[0] = room;
/*for (var i = 0; i < 5; i++) {
 var room = new Room('默认' + (i + 1));
 rooms[room.id] = room;
 }*/

io.sockets.on('connection', function (socket) {
    console.log('Someone connected');
    roomsChanged();

    //登录
    socket.on('login', function (roomId, userName) {
        var result = joinRoom(socket, roomId, userName);
        if (result)
            console.log('[' + roomId + ']' + userName + ' logined');
    });

    //登出
    socket.on('logOut', function () {
        var roomId = socket.roomId;
        leaveRoom(socket);
        console.log('[' + roomId + ']' + socket.user.name + ' logged out');
    });

    //发送消息
    socket.on('postMsg', function (msg) {
        var roomId = socket.roomId,
            userName = socket.user.name,
            users = rooms[roomId].users;
        msg = msg.trim()
            .replace(/<[^<>]+?>/g, '').replace(/\n/g, '<br/>')
            .replace(/\[emoji:\d+\]/g, function (word) {
                var index = (word.substr(7, word.length - 8));
                if (parseInt(index) == index && index > 0 && index <= 110)
                    return tools.format(MsgTemplate.FaceEmoji, index);
                return word;
            })
            .replace(/\[tuzki:\d+\]/g, function (word) {
                var index = (word.substr(7, word.length - 8));
                if (parseInt(index) == index && index > 0 && index <= 69)
                    return tools.format(MsgTemplate.FaceTuzki, index);
                return word;
            })
            .replace(/\@\S+/g, function (word) {
                var name = word.substr(1);
                var index = tools.indexOf(users, function (i, v) {
                    return v.name == name;
                });
                return index > -1 ? tools.format(MsgTemplate.QuoteUser, word) : word;
            });
        emit(socket, EmitType.Normal, 'postSuccess', {msg: msg, userName: userName});
        emit(socket, EmitType.Broadcast, 'newMsg', {msg: msg, userName: userName});
        console.log('[' + roomId + ']' + userName + ':' + msg);
    });

    //发送图片
    socket.on('postImg', function (imgData) {
        var roomId = socket.roomId,
            userName = socket.user.name;
        emit(socket, EmitType.Normal, 'postSuccess', {
            msg: tools.format(MsgTemplate.ImgMsg, imgData),
            userName: userName
        });
        emit(socket, EmitType.Broadcast, 'newMsg', {
            msg: tools.format(MsgTemplate.ImgMsg, imgData),
            userName: userName
        });
        console.log('[' + roomId + ']' + userName + ':[img]');
    });

    //创建房间
    socket.on('createRoom', function (roomName, userName) {
        var roomId = createRoom(roomName);
        var result = joinRoom(socket, roomId, userName);
        if (result)
            console.log('[' + roomId + ']' + userName + ' logined');
    });

    //获取房间
    socket.on('fetchRooms', function () {
        roomsChanged();
    });

    //断开连接
    socket.on('disconnect', function () {
        var roomId = socket.roomId;
        if (!!roomId) {
            var userName = socket.user.name;
            leaveRoom(socket);
            console.log('[' + roomId + ']' + userName + ' logged out');
        } else {
            console.log('Someone disconnected');
        }
    });
});